// Copyright (c) 2022 Presto Labs Pte. Ltd.
// Author: leon

#pragma once

#include <algorithm>
#include <functional>
#include <limits>
#include <map>
#include <string>
#include <vector>
#include <utility>

#include "coin2/base/string_util.h"
#include "coin2/exchange/base/feed/processor.h"
#include "coin2/exchange/base/market/enums.h"
#include "coin2/exchange/base/market/market_exchange_api.h"
#include "coin2/exchange/factory/feed/symbol_updater.h"
#include "cc/coin2/exchange/coingecko/feed_v3/symbol_updater.h"
#include "coin2/exchange/feed.pb.h"

namespace coin2::exchange::coingecko::feed_v3 {
namespace impl {
using coin2::exchange::feed::WebsocketConfig;

class CoingeckoRequestGenerator : public base::feed::RequestGenerator {
 public:
  std::vector<std::string> GenerateRequests(
      const std::vector<std::string>& channels,
      const std::vector<std::string>& symbols,
      const std::map<std::string, std::string>& channel_templates,
      const std::string& request_template) override {
    std::vector<std::string> reqs;
    std::vector<std::string> ch = channels;
    // market
    auto it = std::find(ch.begin(), ch.end(), "market");
    if (it != ch.end()) {
      for (auto& symbol : symbols) {
        std::string c = channel_templates.at("market");
        boost::replace_all(c, "{}", symbol);
        std::string request = request_template;
        boost::replace_all(request, "{channel}", c);
        reqs.push_back(request);
      }
      ch.erase(it);
    }

    std::vector<std::string> reqs_others = RequestGenerator::GenerateRequests(
        ch, symbols, channel_templates, request_template);
    reqs.insert(reqs.end(), reqs_others.begin(), reqs_others.end());
    return reqs;
  }
};

}  // namespace impl
using impl::CoingeckoRequestGenerator;
}  // namespace coin2::exchange::coingecko::feed_v3
